package com.dong.expense.logic;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import android.app.Activity;
import android.app.Application;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;

import androidx.multidex.MultiDexApplication;

import com.dong.expense.utils.LogUtils;
import com.dong.expense.utils.RefInvoke;

import dalvik.system.DexClassLoader;

public class ProxyApplication extends MultiDexApplication {
//	private final static String TAG = ProxyApplication.class.getSimpleName();
//	private static final String appkey = "APPLICATION_CLASS_NAME";
//	private String apkFileName;
//	private String odexPath;
//	private String libPath;
//	private static ProxyApplication mInstance = null;
//	private List<Activity> activityList = new ArrayList<Activity>();
//
//	public static ProxyApplication getInstance() {
//		return mInstance;
//	}
//
	@Override
	public void onCreate() {
//		mInstance = this;
//		initProxy();
	}
//
//	public void clearActivity() {
//		LogUtils.LOGV(TAG, "clearActivity...");
//		for (Activity activity : activityList) {
//			if (null != activity) {
//				activity.finish();
//				activity = null;
//			}
//		}
//		activityList.clear();
//	}
//
//	public void addActivity(Activity activity) {
//		LogUtils.LOGV(TAG, "addActivity...");
//		if (activity != null) {
//			activityList.add(activity);
//		}
//	}
//
//	private void initProxy() {
//		// 如果源应用配置有Appliction对象，则替换为源应用Applicaiton，以便不影响源程序逻辑。
//		String appClassName = null;
//		try {
//			ApplicationInfo ai = this.getPackageManager().getApplicationInfo(
//					this.getPackageName(), PackageManager.GET_META_DATA);
//			Bundle bundle = ai.metaData;
//			if (bundle != null && bundle.containsKey("APPLICATION_CLASS_NAME")) {
//				appClassName = bundle.getString("APPLICATION_CLASS_NAME");
//			} else {
//				return;
//			}
//		} catch (NameNotFoundException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//		Object currentActivityThread = RefInvoke.invokeStaticMethod(
//				"android.app.ActivityThread", "currentActivityThread",
//				new Class[] {}, new Object[] {});
//		Object mBoundApplication = RefInvoke.getFieldOjbect(
//				"android.app.ActivityThread", currentActivityThread,
//				"mBoundApplication");
//		Object loadedApkInfo = RefInvoke.getFieldOjbect(
//				"android.app.ActivityThread$AppBindData", mBoundApplication,
//				"info");
//		RefInvoke.setFieldOjbect("android.app.LoadedApk", "mApplication",
//				loadedApkInfo, null);
//		Object oldApplication = RefInvoke.getFieldOjbect(
//				"android.app.ActivityThread", currentActivityThread,
//				"mInitialApplication");
//		ArrayList<Application> mAllApplications = (ArrayList<Application>) RefInvoke
//				.getFieldOjbect("android.app.ActivityThread",
//						currentActivityThread, "mAllApplications");
//		mAllApplications.remove(oldApplication);
//		ApplicationInfo appinfo_In_LoadedApk = (ApplicationInfo) RefInvoke
//				.getFieldOjbect("android.app.LoadedApk", loadedApkInfo,
//						"mApplicationInfo");
//		ApplicationInfo appinfo_In_AppBindData = (ApplicationInfo) RefInvoke
//				.getFieldOjbect("android.app.ActivityThread$AppBindData",
//						mBoundApplication, "appInfo");
//		appinfo_In_LoadedApk.className = appClassName;
//		appinfo_In_AppBindData.className = appClassName;
//		Application app = (Application) RefInvoke.invokeMethod(
//				"android.app.LoadedApk", "makeApplication", loadedApkInfo,
//				new Class[] { boolean.class, Instrumentation.class },
//				new Object[] { false, null });
//		RefInvoke.setFieldOjbect("android.app.ActivityThread",
//				"mInitialApplication", currentActivityThread, app);
//
//		HashMap mProviderMap = (HashMap) RefInvoke.getFieldOjbect(
//				"android.app.ActivityThread", currentActivityThread,
//				"mProviderMap");
//		Iterator it = mProviderMap.values().iterator();
//		while (it.hasNext()) {
//			Object providerClientRecord = it.next();
//			Object localProvider = RefInvoke.getFieldOjbect(
//					"android.app.ActivityThread$ProviderClientRecord",
//					providerClientRecord, "mLocalProvider");
//			RefInvoke.setFieldOjbect("android.content.ContentProvider",
//					"mContext", localProvider, app);
//		}
//		app.onCreate();
//	}
//
//	@Override
//	protected void attachBaseContext(Context base) {
//		super.attachBaseContext(base);
//		try {
//			File odex = this.getDir("payload_odex", MODE_PRIVATE);
//			File libs = this.getDir("payload_lib", MODE_PRIVATE);
//			odexPath = odex.getAbsolutePath();
//			libPath = libs.getAbsolutePath();
//			apkFileName = odex.getAbsolutePath() + "/payload.apk";
//			LogUtils.LOGE(TAG, "odexPath==>" + odexPath + "==libPath==>"
//					+ libPath + "==apkFileName==>" + apkFileName);
//			File dexFile = new File(apkFileName);
//			if (!dexFile.exists())
//				dexFile.createNewFile();
//			// 读取程序classes.dex文件
//			byte[] dexdata = this.readDexFileFromApk();
//			// 分离出解壳后的apk文件已用于动态加载
//			this.splitPayLoadFromDex(dexdata);
//			// 配置动态加载环境
//			Object currentActivityThread = RefInvoke.invokeStaticMethod(
//					"android.app.ActivityThread", "currentActivityThread",
//					new Class[] {}, new Object[] {});
//			String packageName = this.getPackageName();
//			HashMap mPackages = (HashMap) RefInvoke.getFieldOjbect(
//					"android.app.ActivityThread", currentActivityThread,
//					"mPackages");
//			WeakReference wr = (WeakReference) mPackages.get(packageName);
//			DexClassLoader dLoader = new DexClassLoader(apkFileName, odexPath,
//					libPath, (ClassLoader) RefInvoke.getFieldOjbect(
//							"android.app.LoadedApk", wr.get(), "mClassLoader"));
//			RefInvoke.setFieldOjbect("android.app.LoadedApk", "mClassLoader",
//					wr.get(), dLoader);
//
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}
//
//	private void splitPayLoadFromDex(byte[] data) throws IOException {
//		byte[] apkdata = decrypt(data);
//		int ablen = apkdata.length;
//		byte[] dexlen = new byte[4];
//		System.arraycopy(apkdata, ablen - 4, dexlen, 0, 4);
//		ByteArrayInputStream bais = new ByteArrayInputStream(dexlen);
//		DataInputStream in = new DataInputStream(bais);
//		int readInt = in.readInt();
//		System.out.println(Integer.toHexString(readInt));
//		byte[] newdex = new byte[readInt];
//		System.arraycopy(apkdata, ablen - 4 - readInt, newdex, 0, readInt);
//		File file = new File(apkFileName);
//		try {
//			FileOutputStream localFileOutputStream = new FileOutputStream(file);
//			localFileOutputStream.write(newdex);
//			localFileOutputStream.close();
//
//		} catch (IOException localIOException) {
//			throw new RuntimeException(localIOException);
//		}
//
//		ZipInputStream localZipInputStream = new ZipInputStream(
//				new BufferedInputStream(new FileInputStream(file)));
//		while (true) {
//			ZipEntry localZipEntry = localZipInputStream.getNextEntry();
//			if (localZipEntry == null) {
//				localZipInputStream.close();
//				break;
//			}
//			String name = localZipEntry.getName();
//			if (name.startsWith("lib/") && name.endsWith(".so")) {
//				File storeFile = new File(libPath + "/"
//						+ name.substring(name.lastIndexOf('/')));
//				storeFile.createNewFile();
//				FileOutputStream fos = new FileOutputStream(storeFile);
//				byte[] arrayOfByte = new byte[1024];
//				while (true) {
//					int i = localZipInputStream.read(arrayOfByte);
//					if (i == -1)
//						break;
//					fos.write(arrayOfByte, 0, i);
//				}
//				fos.flush();
//				fos.close();
//			}
//			localZipInputStream.closeEntry();
//		}
//		localZipInputStream.close();
//
//	}
//
//	private byte[] readDexFileFromApk() throws IOException {
//		ByteArrayOutputStream dexByteArrayOutputStream = new ByteArrayOutputStream();
//		ZipInputStream localZipInputStream = new ZipInputStream(
//				new BufferedInputStream(new FileInputStream(
//						this.getApplicationInfo().sourceDir)));
//		while (true) {
//			ZipEntry localZipEntry = localZipInputStream.getNextEntry();
//			if (localZipEntry == null) {
//				localZipInputStream.close();
//				break;
//			}
//			if (localZipEntry.getName().equals("classes.dex")) {
//				byte[] arrayOfByte = new byte[1024];
//				while (true) {
//					int i = localZipInputStream.read(arrayOfByte);
//					if (i == -1)
//						break;
//					dexByteArrayOutputStream.write(arrayOfByte, 0, i);
//				}
//			}
//			localZipInputStream.closeEntry();
//		}
//		localZipInputStream.close();
//		return dexByteArrayOutputStream.toByteArray();
//	}
//
//	// //直接返回数据，读者可以添加自己解密方法
//	private byte[] decrypt(byte[] data) {
//		return data;
//	}
}
